/*
 * File Name：SpeechControler.java
 * Copyright：Copyright 2008-2014 CiWong.Inc. All Rights Reserved.
 * Description： SpeechControler.java
 * Modify By：jejun
 * Modify Date：2014-2-10
 * Modify Type：Add
 */
package com.ciwong.epaper.modules.evaluate.util;

import android.os.Handler;

import com.ciwong.epaper.application.EApplication;
import com.ciwong.epaper.modules.epaper.bean.Answer;
import com.ciwong.epaper.modules.epaper.bean.WorkAnswers;
import com.ciwong.epaper.modules.evaluate.bean.AnswerRecorder;
import com.ciwong.epaper.modules.evaluate.bean.RepeatAnswerInfo;
import com.ciwong.epaper.modules.evaluate.bean.Sentence;
import com.ciwong.epaper.util.DialogUtil;
import com.ciwong.epaper.util.FeedbackUtil;
import com.ciwong.libs.audio.play.AudioPlayer;
import com.ciwong.libs.oralevaluate.IEvaluateEngine;
import com.ciwong.libs.oralevaluate.OnEvaluateListener;
import com.ciwong.libs.oralevaluate.bean.EvaluateResult;
import com.ciwong.libs.oralevaluate.bean.Word;
import com.ciwong.libs.oralevaluate.yunzhisheng.YZSEngine;
import com.ciwong.libs.utils.CWLog;
import com.ciwong.libs.utils.NetworkUtils;
import com.ciwong.libs.widget.CWToast;
import com.ciwong.mobilelib.ui.BaseActivity;
import com.ciwong.mobilelib.utils.ToastUtil;
import com.unisound.edu.oraleval.sdk.sep15.IOralEvalSDK;
import com.unisound.edu.oraleval.sdk.sep15.SDKError;

import java.util.ArrayList;

/**
 * 语音评测控制基类
 *
 * @author jejun
 * @version ciwong v.1.0 2014-2-10
 * @since ciwong v.1.0
 */
public abstract class SpeechController implements OnEvaluateListener {

    public static final String TAG = "SpeechController";
    public static final String ASIDE_AUDIO_TAG = "asideTag";// 标记旁白音频
    public static final String ASIDE_AUDIO_TAG_EVALUATE = "pcm";//p


    /**
     * 跟读播放原音状态
     */
    public static final int PLAY_STATUS_PLYAING_1 = 1;

    /**
     * 年级id
     */
    private int mGradeId;


    /**
     * 语音播放评分结果(you_can_do_better,good job,excellent)
     */
    public static final int PLAY_STATUS_PLYAING_4 = 5;

    /**
     * 正常状态
     */
    public static final int OPERATE_STATUS_NORMAL = 0;

    /**
     * 正在进行
     */
    public static final int OPERATE_STATUS_PLAYING = 1;

    /**
     * 正常的录音状态，即第一次的录音
     */
    public static final int OPERATE_STATUS_RECORDING = 2;

    /**
     * 正常的播放暂停状态
     */
    public static final int OPERATE_STATUS_PLAY_PAUSE = -1;

    /**
     * 正常的录音暂停状态
     */
    public static final int OPERATE_STATUS_RECORD_PAUSE = -2;

    /**
     * 对比播放原音及录音状态(用户点击每一行)
     */
    public static final int OPERATE_STATUS_COMPARISONING = 3;

    /**
     * 对比播放原音及录音暂停状态
     */
    public static final int OPERATE_STATUS_COMPARISON_PAUSE = -3;

    /**
     * 停止状态
     */
    public static final int OPERATE_STATUS_STOP = 5;

    public String uuid;

    protected int readDuration;// 系统通读课文每句或每一个单词之间间隔

    protected int repeatDuration;// 单词或句子重复间隔时间


    protected int playStatus;// 跟读状态

    public int operateStatus = OPERATE_STATUS_NORMAL;// 操作状态

    public ArrayList<AnswerRecorder> answerRecorders;


    protected long audioDuration = 3500;// 单词播放时长

    protected static final int RECORD_ADD_DURATION = 3500;// 录音增加的时长

    protected int answerCount;// 实际要提交的答案数（有些单词音频文件错误，不能跟读）

    public int currentListenAndRepeatIndex, cacheListenAndRepeatIndex;// 当前单词所在界面索引，缓存当前跟读的单词索引

    protected Handler mHandler = new Handler();

    protected BaseActivity mContext;

    protected IEvaluateEngine eEngine;

    protected int totalTime = 0;

    public ArrayList<WorkAnswers<RepeatAnswerInfo>> userAnswerseList = new ArrayList<WorkAnswers<RepeatAnswerInfo>>();

    protected boolean isPlayRecord = false;// 是否回放录音

    protected boolean isPlayAssess = true;// 是否播放评价语

    public boolean isPlayAssess() {
        return isPlayAssess;
    }

    public void setPlayAssess(boolean playAssess) {
        isPlayAssess = playAssess;
    }

    public boolean isPlayRecord() {
        return isPlayRecord;
    }

    public void setPlayRecord(boolean playRecord) {
        isPlayRecord = playRecord;
    }

    protected SpeechController(BaseActivity context) {
        this.mContext = context;
        readDuration = 1000;
    }

    /**
     * 初始化
     */
    protected void initYZSEngine() {
        if (EApplication.getInstance().getClazz() != null) {
            mGradeId = EApplication.getInstance().getClazz().getGradeId();
        }
        eEngine = new YZSEngine(mContext);
        if (mGradeId >= 1101 && mGradeId <= 1106) {
            eEngine.SetScoreAdjuest(1.8f);
        } else {
            eEngine.SetScoreAdjuest(1.7f);
        }
        eEngine.setEvaluateListener(SpeechController.this);

    }


    /**
     * 是否是暂停状态
     *
     * @return
     */
    public boolean isPause() {
        return operateStatus == OPERATE_STATUS_COMPARISON_PAUSE
                || operateStatus == OPERATE_STATUS_PLAY_PAUSE
                || operateStatus == OPERATE_STATUS_RECORD_PAUSE;
    }

    /**
     * 設置重复间隔时间
     *
     * @param duration 时间
     */
    public void setRepeatDuration(int duration) {
        repeatDuration = duration;
    }

    /**
     * 设置 系统通读课文每句之间时间间隔
     *
     * @param duration 时间间隔
     */
    public void setReadDuration(int duration) {
        readDuration = duration;
    }

    /**
     * 显示错误信息
     *
     * @param resId 信息资源ID
     */
    public void showMsg(final int resId) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                CWToast.centerSquareError(mContext, resId).show();
            }
        });
    }


    /**
     * 获取平均分
     *
     * @return
     */
    public int getAvgScore() {
        int len = answerRecorders.size();
        float total = 0;
        for (AnswerRecorder ar : answerRecorders) {
            if (ar != null) {
                total += ar.getScore();
            }
        }
        int avg = (int) (total / len);
        return avg;
    }


    /**
     * 如果多次跟读未成功评测，则显示直接结果（随机分数）
     */
    public abstract void randomShow();


    protected void playResultScore(float score) {
        if (isPause() || operateStatus == OPERATE_STATUS_STOP) {
            return;
        }
        // int raw = SpeechUtils.getResultSoundRaw(item_my_work_child_score);
        int raw = 0;
        if (score < SpeechUtils.SCORE_1) {
            raw = SpeechUtils.getRandomRaw(SpeechUtils.LEVEL_A);
        } else if (score < SpeechUtils.SCORE_2) {
            raw = SpeechUtils.getRandomRaw(SpeechUtils.LEVEL_B);
        } else if (score < SpeechUtils.SCORE_3) {
            raw = SpeechUtils.getRandomRaw(SpeechUtils.LEVEL_C);
        } else if (score < SpeechUtils.SCORE_4) {
            raw = SpeechUtils.getRandomRaw(SpeechUtils.LEVEL_D);
        } else {
            raw = SpeechUtils.getRandomRaw(SpeechUtils.LEVEL_E);
        }

        try {

            AudioPlayer.getInstance().play(raw, mContext, "pcm");
        } catch (NullPointerException e) {
            e.getStackTrace();
        }

    }

    public AnswerRecorder onEvaluated(int score, float integrity, float fluency, float pronunciation, String path,
                                      boolean playResult) {
        CWLog.i(TAG,
                "currentListenAndRepeatIndex:" + currentListenAndRepeatIndex
                        + "     size:" + answerRecorders.size());
        AnswerRecorder ar = null;
        if (currentListenAndRepeatIndex < answerRecorders.size()) {
            ar = answerRecorders.get(currentListenAndRepeatIndex);
            // item_my_work_child_score = SpeechUtils.scoreOptimize(item_my_work_child_score);
            //重读直接覆盖
            ar.setScore(score);
            ar.setIntegrity(integrity);
            ar.setFluency(fluency);
            ar.setPronunciation(pronunciation);
            ar.setSoundUrl(path);

            CWLog.i("debug",
                    "onEvaluated transcoding:" + ar.getSoundUrl()
                            + "    currentListenAndRepeatIndex:"
                            + currentListenAndRepeatIndex);
        }
        if (playResult) {
            playResultScore(/* ar.getScore() */score);
        }
        return ar;
    }

    @Override
    public void onInit(int result) {

    }

    @Override
    public void onError(IOralEvalSDK evalSDK, SDKError sdkError, IOralEvalSDK.OfflineSDKError offlineSDKError) {
        CWLog.e("debug", "onError:" + sdkError);
        String logDesc = "###errorCode####" + sdkError.toString();
        FeedbackUtil.getInstance().addFeedbackLog(FeedbackUtil.FEEDBACK_TYPE_EVALUATE, logDesc, "评分失败");
        // BaseApplication.log = YZSEngine.sb;
        SDKError.Category category = sdkError.category;
        if (SDKError.Category.Network == category) {
            if (!NetworkUtils.isOnline()) {
                ToastUtil.INSTANCE.toastCenterNoNetError();
            } else {
                ToastUtil.INSTANCE.toastCenterError("评分过程遇到错误，网络不稳定：" + sdkError.errno);
            }
            randomScore();
        } else if (SDKError.Category.Device == category) {
            operateStatus = OPERATE_STATUS_STOP;
            onStop(-3, null, "");//设置权限
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    DialogUtil.showSettingPermissions(mContext);
                }
            });
        } else {
            randomScore();
            ToastUtil.INSTANCE.toastCenterError("评分过程遇到错误，错误信息：" + sdkError.errno);
        }
    }

    /**
     * 随机打分
     */
    private void randomScore() {
        int randomNum = 0;
        EvaluateResult evaluateResult = new EvaluateResult();
        evaluateResult.setScore(randomNum);
        evaluateResult.setWords(new ArrayList<Word>());
        onStop(-2, evaluateResult, "");
    }

    /**
     * 语音评测监听接口
     *
     * @author jejun
     */
    public static interface OnSpeechListener {
        /**
         * 所有的逐句跟读、单词跟读、选段背诵、独立通读都完成
         *
         * @param userAnswerseList
         * @param uuid
         * @param score
         */
        void onAllComplete(Answer workAnswer,
                           ArrayList<WorkAnswers<RepeatAnswerInfo>> userAnswerseList,
                           ArrayList<AnswerRecorder> answerRecorders,
                           String uuid, int score);

        /**
         * 原音读完
         */
        void onListenerComplete();

        /**
         * 开启录音动画
         */
        void startRecordAnim();

        /**
         * 完成一次跟读、通读或背诵、单词跟读
         * 得分
         */
        void onComplete();

        /**
         * 停止录音动画
         */
        void stopRecordAnim();

        /**
         * 更新播放进度
         */
        void updateProgress(int total, int progress);


        public void notFile();

        void onSaveRecord(
                ArrayList<WorkAnswers<RepeatAnswerInfo>> userAnswersList,
                ArrayList<AnswerRecorder> answerRecorderList, String saveUUid);

        void onSaveSentenceRecord(ArrayList<Sentence> sentenceList);


        void repeatReadFinsh(AnswerRecorder answerRecorder, EvaluateResult evaluateResult, String yzsAudioUrl);

        void recError(IOralEvalSDK evalSDK, SDKError sdkError, IOralEvalSDK.OfflineSDKError offlineSDKError);
    }
}
